package com.db.utils;

import exam.common.Utils;
import org.apache.poi.ss.formula.functions.T;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Xiongx
 * @version 1.0
 * @date 2021/4/21 9:27
 * @since JDK 1.8
 */
public class DBUtils {


    private static String url;

    private static String driver;

    private static String password;

    private static String username;

    private static boolean isBoolean;

    private static Map<String, String> objectMap=new HashMap<>();

    public static void initDBUtils(String url1,String driver1,String password1,String username1){
        isBoolean=true;
        url=url1;
        driver=driver1;
        password=password1;
        username=username1;
    }

    public static Map<String, String> getDataScourse(){
        objectMap.put("url",url);
        objectMap.put("driver",driver);
        objectMap.put("password",password);
        objectMap.put("username",username);
        return objectMap;
    }

    /**
     *创建连接通道
     * @return 连接通道
     */
    private static Connection getConbection(){
        checkDBConnectionInit();
        return new Connectionzz().createConnection(driver,url,username,password);
    }

    /**
     * 校验数据连接是否初始化
     */
    private static void checkDBConnectionInit(){
        try {
            if(!isBoolean){
                throw new Exception("数据连接信息未初始化");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }




    //执行查询sql
    private static ResultSet sqlExecuteQuery(String sql){
        Statement stmt = null;
        Connection conn = null;
        ResultSet rs=null;
        try {
            conn=getConbection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
        }catch (Exception e){
            e.printStackTrace();
        }
        return rs;
    }



    /**
     * sql 执行
     * @param sql
     * @return
     */
    private static boolean sqlExecute(String sql){
        boolean flag=false;
        Statement stmt = null;
        Connection conn = null;
        try {
            conn=getConbection();
            stmt = conn.createStatement();
            flag = stmt.execute(sql);
        }catch (Exception e){
            e.printStackTrace();
        }
        return flag;
    }


    public static void main(String[] args) {
        String sql="";
    }

    private static String sqlStringFormart(String sql,String[] arr){
        sql= sql.replaceAll("\\?","%s");
        return String.format(sql, arr);
    }


    //获取字段列表
    private static String[] getFeildList(ResultSet rs){
        try {
            ResultSetMetaData rsmd = rs.getMetaData();
            String [] lie=new String[rsmd.getColumnCount()];
            for (int i = 1; i <rsmd.getColumnCount()+1; i++) {
                lie[i-1]=rsmd.getColumnName(i);
            }
            return lie;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     *
     * @param rs 查询的结果集
     * @param feildName  属性列表
     * @return
     */
    private static List<Map<String, Object>> selectMapList(ResultSet rs,String [] feildName){
       List<Map<String, Object>> maps=new ArrayList<>();
        try {
            while (rs.next()) {
                Map<String, Object> objectMap=new HashMap<>();
                for (int i = 0; i < feildName.length ; i++) {
                    Object value=rs.getObject(feildName[i]);
                    objectMap.put(feildName[i],value);
                }
                maps.add(objectMap);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return maps;
    }

    /**
     * sql查询多个
     * @param rs
     * @param feildName
     * @param cls
     * @param <T>
     * @return
     */
    private static <T> List<T> selectBeanList(ResultSet rs,String [] feildName,Class<T> cls){
        List<T> beans=new ArrayList<>();
        Field[] fields=cls.getDeclaredFields();
        try {
            while (rs.next()) {
                T t=cls.newInstance();
                for (int i = 0; i < feildName.length ; i++) {
                    Object value=rs.getObject(feildName[i]);
                    Field field=Utils.getFieldByName(feildName[i],fields);
                    field.setAccessible(true);
                    field.set(t,value);
                }
                beans.add(t);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return beans;
    }


    /**
     * 查询一个
     * @param rs
     * @param feildName
     * @param cls
     * @param <T>
     * @return
     */
    private static <T> T selectBeanOne(ResultSet rs,String [] feildName,Class<T> cls){
        Field[] fields=cls.getDeclaredFields();
        try {
            while (rs.next()) {
                T t=cls.newInstance();
                for (int i = 0; i < feildName.length ; i++) {
                    Object value=rs.getObject(feildName[i]);
                    Field field=Utils.getFieldByName(feildName[i],fields);
                    field.setAccessible(true);
                    field.set(t,value);
                }
                return t;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 查询一个
     * @param rs
     * @param feildName
     * @return
     */
    private static Map<String, Object> selectMapOne(ResultSet rs,String[] feildName){
        Map<String, Object> objectMap=null;
        try {
            while (rs.next()) {
                objectMap=new HashMap<>(1);
                for (int i = 0; i < feildName.length ; i++) {
                    Object value=rs.getObject(feildName[i]);
                    objectMap.put(feildName[i],value);
                }
                return objectMap;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return objectMap;
    }


    /**
     * 通过sql查询数据集合
     * @param sql
     * @return
     */
    public static List<Map<String, Object>> selectMapList(String sql){
        ResultSet resultSet=sqlExecuteQuery(sql);
        String[] fieldList=getFeildList(resultSet);
        return selectMapList(resultSet,fieldList);
    }


    /**
     * 通过sql查询一个
     * @param sql
     * @return
     */
    public static Map<String, Object> selectMapOne(String sql){
        ResultSet resultSet=sqlExecuteQuery(sql);
        String[] fieldList=getFeildList(resultSet);
        return selectMapOne(resultSet,fieldList);
    }

    /**
     * 使用占位符查询
     * @param sql
     * @param args
     * @return
     */
    public static List<Map<String, Object>> selectMapList(String sql,String[]args){
        sql=sqlStringFormart(sql,args);
        return selectMapList(sql);
    }


    /**
     * 查询list集合
     * @param sql
     * @param cls
     * @param <T>
     * @return
     */
    public static  <T> List<T> selectBeanList(String sql,Class<T> cls){
        ResultSet resultSet=sqlExecuteQuery(sql);
        String[] fieldList=getFeildList(resultSet);
        return selectBeanList(resultSet,fieldList,cls);
    }


    public static <T> T selectBeanOne(String sql,Class<T> cls){
        ResultSet resultSet=sqlExecuteQuery(sql);
        String[] fieldList=getFeildList(resultSet);
        return selectBeanOne(resultSet,fieldList,cls);
    }


    /**
     * 使用占位符查询list集合
     * @param sql
     * @param cls
     * @param args
     * @param <T>
     * @return
     */
    public static  <T> List<T> selectBeanList(String sql,Class<T> cls,String[] args){
        sql=sqlStringFormart(sql,args);
        return selectBeanList(sql,cls);
    }

    /**
     * 查询一个
     * @param sql
     * @param cls
     * @param args
     * @param <T>
     * @return
     */
    public static <T> T selectBeanOne(String sql,Class<T> cls,String[] args){
        sql=sqlStringFormart(sql,args);
        return selectBeanOne(sql,cls);
    }




}
